package com.acmen.easyapi.executor.impl;

import com.acmen.easyapi.constant.AuthConstants;
import com.acmen.easyapi.executor.AuthorizationExe;
import com.acmen.easyapi.factory.EnvFactory;
import com.acmen.easyapi.model.Environment;
import com.acmen.easyapi.model.Response;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 授权认证执行器实现
 *
 * @Author acmen
 */
@Component
public class AuthorizationExeImpl implements AuthorizationExe {
    @Resource
    private EnvFactory envFactory;
    private RestTemplate restTemplate = new RestTemplate();
    @Value("${oauth.clientId:test}")
    private String clientId;
    @Value("${oauth.clientSecret:b711b22c3ee74ce88dcbaa964da7019b}")
    private String clientSecret;
    @Value("${oauth.scope:read,write}")
    private String scope;

    /**
     * 授权参数
     */
    private static final String[] AUTH_PARAM_NAMES = {"orgNo","account","password"};

    /**
     * 授权服务路径
     */
    private static final String AUTH_PATH = "/oauth/token/password";



    public Response authorize(HttpServletRequest request,HttpServletResponse response) {
        String env = request.getParameter("env");
        Optional<Environment> envOptional = envFactory.getEnvironmens().stream().filter(e->e.getName().equalsIgnoreCase(env)).findFirst();
        if(envOptional.isPresent() == false){
            return Response.failure(env+"环境没有配置授权地址");
        }
        Map authParams = new HashMap();
        for(String paramName : AUTH_PARAM_NAMES){
            authParams.put(paramName,request.getParameter(paramName));
        }
        Map<String,Object> cookieItems = new HashMap(authParams);
        String url = envOptional.get().getBasePath() + AUTH_PATH;
        HttpHeaders reuqesHeaders = new HttpHeaders();
        reuqesHeaders.setContentType(MediaType.APPLICATION_JSON);
        JSONObject reuqestBody = new JSONObject(authParams);
        reuqestBody.put("clientId", clientId);
        reuqestBody.put("clientSecret", clientSecret);
        reuqestBody.put("scope", scope);
        HttpEntity requestEntity = new HttpEntity(reuqestBody,reuqesHeaders);
        try{
            Response<Map> res = restTemplate.postForObject(url,requestEntity,Response.class);
            if(res.isSuccess()){
                cookieItems.put(AuthConstants.ACCESS_TOKEN,res.get().get(AuthConstants.ACCESS_TOKEN));
                cookieItems.put(AuthConstants.JWT,res.get().get(AuthConstants.JWT));
            }
            return res;
        }catch (Exception e){
            return Response.failure("认证失败！");
        }finally {
            saveToCookie(cookieItems,response);
        }
    }


    /**
     * @param cookieItems
     * @param response
     */
    private void saveToCookie( Map<String,Object> cookieItems, HttpServletResponse response) {
        cookieItems.forEach((key,value)->{
            Cookie cookie = new Cookie(key, String.valueOf(value));
            cookie.setPath("/");
            cookie.setMaxAge(60 * 60 * 24 * 7);//设置其生命周期
            response.addCookie(cookie);
        });
    }
}
